package com.oliver.oliveraiagent.controller;

import com.oliver.oliveraiagent.agent.OliverManus;
import com.oliver.oliveraiagent.app.LoveApp;
import com.oliver.oliveraiagent.common.BaseResponse;
import com.oliver.oliveraiagent.common.ResultUtils;
import com.oliver.oliveraiagent.model.entity.User;
import com.oliver.oliveraiagent.service.UserService;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.tool.ToolCallback;
import org.springframework.http.MediaType;
import org.springframework.http.codec.ServerSentEvent;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import reactor.core.publisher.Flux;

import java.io.IOException;

/**
 * @ClassName AiAgentController
 * @Description TODO
 * @Author snow
 * @Date 2025/5/24 20:18
 **/

@RestController
@RequestMapping("/ai")
public class AiAgentController {

    @Resource
    private LoveApp loveApp;

    @Resource
    private UserService userService;

    /**
     * 同步调用大模型接口
     *
     * @param message
     * @param chatId
     * @return
     */
    @GetMapping("/love_app/chat/sync")
    public String doChatWithLoveAppSync(@RequestParam("message") String message,
                                        @RequestParam("chatId") String chatId,
                                        HttpServletRequest request) {
        User loginUser = userService.getLoginUser(request);
        return loveApp.doChat(message, chatId, loginUser.getUserId());
    }

    /**
     * 流式返回
     *
     * @param message
     * @param chatId
     * @return
     */
    @GetMapping(value = "/love_app/chat/sse", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<String> doChatWithLoveAppSSE(@RequestParam("message") String message, @RequestParam("chatId") String chatId) {
        return loveApp.doChatByStream(message, chatId);
    }

    @GetMapping(value = "/love_app/chat/serverEvent")
    public Flux<ServerSentEvent<String>> doChatWithLoveAppServerEvent(@RequestParam("message") String message, @RequestParam("chatId") String chatId) {
        return loveApp.doChatByStream(message, chatId)
                .map(chunk -> ServerSentEvent.<String>builder()
                        .data(chunk)
                        .build());
    }

    @GetMapping("/love_app/chat/sse/emitter")
    public BaseResponse<SseEmitter> doChatWithLoveAppSseEmitter(@RequestParam("message") String message,
                                                                @RequestParam("chatId") String chatId,
                                                                HttpServletRequest request) {
        User loginUser = userService.getLoginUser(request);
        // 创建一个超时时间较长的 SseEmitter
        SseEmitter emitter = new SseEmitter(180000L); // 3分钟超时
        // 获取 Flux 数据流并直接订阅
        loveApp.doChatByStreamByUserId(message, chatId,loginUser.getUserId())
                .subscribe(
                        // 处理每条消息
                        chunk -> {
                            try {
                                emitter.send(chunk);
                            } catch (IOException e) {
                                emitter.completeWithError(e);
                            }
                        },
                        // 处理错误
                        emitter::completeWithError,
                        // 处理完成
                        emitter::complete
                );
        // 返回emitter
        return ResultUtils.success(emitter);
    }

    @Resource
    private ToolCallback[] allTools;

    @Resource
    private ChatModel dashscopeChatModel;

    /**
     * 流式调用 Manus 超级智能体
     *
     * @param message
     * @return
     */
    @GetMapping("/manus/chat")
    public SseEmitter doChatWithManus(@RequestParam("message") String message, HttpServletRequest request) {
        User loginUser = userService.getLoginUser(request);
        OliverManus oliverManus = new OliverManus(allTools, dashscopeChatModel, loginUser.getUserId());
        return oliverManus.runStream(message);
    }
}
